
#include "kvstorage.h"
#include "log.h"

#define ADMIN_NAME_TEXT     "user:admin"
#define ADMIN_PASSWORD_TEXT "password:123"

void KVStorage::open(std::string path) {
    try {
        m_conn.open(path);
        m_conn.execute(R"(  
            CREATE TABLE IF NOT EXISTS kvset (  
                key TEXT NOT NULL UNIQUE,  
                value TEXT NOT NULL  
            );  
        )");

        const char* stmt = "INSERT OR IGNORE INTO kvset (key, value) values (?, ?);";
        m_conn.execute(stmt, ADMIN_NAME_TEXT, (const char*)ADMIN_PASSWORD_TEXT);
    } catch (const std::exception& e) {
        loge(" open error : {}", e.what());
        throw;
    }
}

void KVStorage::close(void) {
    m_conn.close();
}

void KVStorage::kvset(std::string k, std::string v) {
    const char* stmt = R"(
        INSERT OR REPLACE INTO kvset(key, value) VALUES (?, ?);
    )";
    m_conn.execute(stmt, k, v);
}

std::string KVStorage::kvget(std::string k) {
    const char* stmt = R"(select key, value from kvset where key = ?;)";
    auto r           = m_conn.execute<std::tuple<std::string, std::string>>(stmt, k);

    if (r.empty()) {
        return std::string();
    }
    // for (const auto& [key, value] : r) {
    //     logi("key: {}, value: {}", key.c_str(), value.c_str());
    // }
    return std::get<1>(r.at(0));
}

std::unordered_map<std::string, std::string> KVStorage::kv_keys(std::string k) {
    std::unordered_map<std::string, std::string> ret;
    const char* stmt = R"(select key, value from kvset where key LIKE ?;)";
    auto r           = m_conn.execute<std::tuple<std::string, std::string>>(stmt, k + "%");

    for (const auto& [key, value] : r) {
        // logi("key: {}, value: {}", key.c_str(), value.c_str());
        ret[key] = value;
    }

    // for (const auto& [key, value] : ret) {
    //     logi("unordered_map key: {}, value: {}", key.c_str(), value.c_str());
    // }
    return ret;
}

void KVStorage::kvdel(std::string k) {
    const char* stmt = R"(delete from kvset where key = ?;)";
    m_conn.execute(stmt, k);
}

void KVStorage::kv_del_keys(std::string k) {
    const char* stmt = R"(delete from kvset where key LIKE ?;)";
    m_conn.execute(stmt, k + "%");
}
